import { lazy, Suspense } from 'react'
import { createBrowserRouter, Navigate, redirect, RouteObject, useRouteError } from 'react-router-dom'
import { Flex, Skeleton } from 'antd'
import { getItem, TOKEN, hsHandleLoginCode, PERMISSIONROUTERLIST, __DEV__, setItem, USERRESULT } from '@hs-admin/utils'
import { originMenuOptions } from '@/utils/menu'
import { codeGetToken, getUserInfo } from '@/api/login'
import { commonRouteLoader } from '@hs-admin/node'

const Layout = lazy(() => import('@/views/Layout'))
const Login = lazy(() => import('@/views/Login'))
const Demo = lazy(() => import('@/views/Demo'))
const DataItemDetail = lazy(() => import('@/views/Detail/DataItem'))
const AtlasDetail = lazy(() => import('@/views/Detail/Atlas'))
const Setting = lazy(() => import('@/views/Setting'))
const DataItemSetting = lazy(() => import('@/views/Setting/DataItem'))
const DataItemSettingEdit = lazy(() => import('@/views/Setting/DataItem/edit'))
const AtlasSetting = lazy(() => import('@/views/Setting/Atlas'))
const Approval = lazy(() => import('@/views/Approval'))
const ApprovalExport = lazy(() => import('@/views/Approval/DataExport'))
const Empty = lazy(() => import('@/views/Empty'))
const Monitor = lazy(() => import('@/views/Monitor'))
const Suggestion = lazy(() => import('@/views/Monitor/Suggestion'))
const CompanyRank = lazy(() => import('@/views/Setting/CompanyRank'))
const CompanyQualifications = lazy(() => import('@/views/Setting/CompanyQualifications'))
const OperateDemandOrder = lazy(() =>
  import('@hs-server/components').then((it) => ({
    default: it.OperateDemandOrder
  }))
)

function withLoading(compnent: JSX.Element) {
  return <Suspense fallback={<Skeleton active />}>{compnent}</Suspense>
}

const routeChildren: Array<{
  name?: string
  path: string
  element: JSX.Element
  children?: any[]
  loader?: (params?: any, prefix?: string) => null
}> = [
  {
    path: '*',
    element: withLoading(<Navigate to="/setting" replace />)
  },
  {
    path: '',
    element: withLoading(<Navigate to="/setting" replace />)
  },
  {
    path: 'setting',
    element: withLoading(<Setting />),
    children: [
      {
        path: 'dataItem',
        element: withLoading(<DataItemSetting />),
        children: [
          {
            path: 'edit',
            element: withLoading(<DataItemSettingEdit />)
          }
        ]
      },
      {
        path: 'atlas',
        element: withLoading(<AtlasSetting />)
      },
      {
        path: 'atlasDetail',
        element: withLoading(<AtlasDetail />)
      },
      {
        path: 'dataItemDetail',
        element: withLoading(<DataItemDetail />)
      },
      {
        path: 'companyRank',
        element: withLoading(<CompanyRank />)
      },
      {
        path: 'companyQualifications',
        element: withLoading(<CompanyQualifications />)
      }
    ]
  },
  {
    path: 'approval',
    element: withLoading(<Approval />),
    children: [
      {
        path: 'export',
        element: withLoading(<ApprovalExport />)
      }
    ]
  },
  {
    path: 'monitor',
    element: withLoading(<Monitor />),
    children: [
      {
        path: 'suggestion',
        element: withLoading(<Suggestion />)
      },
      {
        path: 'demandOrder',
        element: withLoading(<OperateDemandOrder from="dataOperate" />)
      }
    ]
  },
  {
    path: '404',
    element: withLoading(<Empty />)
  }
]
if (__DEV__) {
  routeChildren.push({
    path: 'demo',
    element: withLoading(<Demo />)
  })
}
routeChildren.forEach((first) => {
  first.loader ??= () => commonRouteLoader({}, 'operate/')
  first.children?.forEach((second) => {
    second.loader ??= () => commonRouteLoader({}, 'operate/')
    second.children?.forEach((third: { loader: () => null }) => {
      third.loader ??= () => commonRouteLoader({}, 'operate/')
    })
  })
})

function ErrorBoundary() {
  const error = useRouteError() as {
    message?: string
    status?: number
  }
  let text = ''
  if (error.message?.includes('Failed to fetch dynamically imported module')) {
    text = ''
    window.location.reload()
  } else if (error.message?.length) {
    text = error.message
  } else if (error.status === 404) {
    text = '页面不存在'
  } else if (error.status === 403) {
    text = '您没有该页面权限'
  } else {
    text = '未知错误'
  }
  return (
    <Flex align="center" justify="center" style={{ height: '100%' }}>
      <h1>{text}</h1>
    </Flex>
  )
}

const routeConfig: RouteObject[] = [
  {
    path: '/',
    element: withLoading(<Layout />),
    children: routeChildren,
    loader: async ({ request }) => {
      const token = getItem(TOKEN)
      if (!token) {
        return redirect('/login')
      }
      const menuOptions = getItem('MENUOPTIONS_OPERATE')
      if (!menuOptions?.length) {
        return redirect('/login')
      }
      return null
      // 校验跳转路由是否有权限
      const configMenuList = getItem(PERMISSIONROUTERLIST) || []
      const _isPass = configMenuList.some((item: string) => request.url.includes(item))
      if (_isPass) {
        return null
      } else {
        return redirect(configMenuList[0])
      }
    },
    errorElement: <ErrorBoundary />
  },
  {
    path: '/login',
    element: withLoading(<Login />),
    loader: async ({ request }) => {
      return hsHandleLoginCode(
        request.url,
        originMenuOptions,
        codeGetToken,
        getUserInfo,
        // 存储当前系统所有权限和用户信息
        (res) => {
          const permissions = res.permissions.map((item: any) => item.name)
          setItem('PERMISSIONS_OPERATE', permissions)
          setItem(USERRESULT, res)
          return permissions
        },
        // 存储有权限的路由和要展示的菜单
        (permissionRouterList, menuOptions) => {
          setItem('PERMISSIONROUTERLIST_OPERATE', [...permissionRouterList])
          if (!menuOptions.length) {
            menuOptions = [
              {
                label: '404',
                key: '/404',
                show: 1
              }
            ]
          }
          setItem('MENUOPTIONS_OPERATE', menuOptions)
        }
      )
    },
    errorElement: <ErrorBoundary />
  }
]

const router = createBrowserRouter(routeConfig, {
  basename: '/operate'
})

// Clean up on module reload (HMR)
// https://vitejs.dev/guide/api-hmr
if (import.meta.hot) {
  import.meta.hot.dispose(() => router.dispose())
}

export default router
